function [Filter,MelFrequencyVector] = melfilter(N,FrequencyVector,hWindow)
% melfilter         Create a mel frequency filterbank
%
%   [Filter,MelFrequencyVector] = melfilter(N,FrequencyVector,hWindow)
%
%   Generates a filter bank matrix with N lineary spaced filter banks, 
%   in the Mel frequency domain, that are overlapped by 50%.
%
%   `N` the number of filter banks to construct.
%
%   `FrequencyVector` a vector indicating the frequencies at which to
%   evaluate the filter bank coeffiecents.
%
%   `hWindow` a handle to the windowing function that determines the shape
%   of the filterbank. The default is hWindow = @triang
%
%   `Filter` is sparse matrix of size [N numel(FrequencyVector)].
%
%   `MelFrequencyVector` is a vector containing the Mel frequency values
%
%   Example
%       N = 50;
%       Fs = 10000;
%       x = sin(2*pi*110*(0:(1/Fs):5));
%       [Pxx,F] = periodogram(x,[],512,Fs);
%
%       Filter = melfilter(N,F);
%       Filter = melfilter(N,F,@rectwin);
%       [Filter,MF] = melfilter(N,F,@blackmanharris);
%
%       FPxx = Filter*Pxx;
%
%   See also
%       melfilter melbankm mfcceps hz2mel
%

%% Author Information
%   Pierce Brady
%   Smart Systems Integration Group - SSIG
%	Cork Institute of Technology, Ireland.
% 

%% Reference
%   F. Zheng, G. Zhang, Z. Song, "Comparision of Different Implementations
%   of MFCC", Journal of Computer Science & Technology, vol. 16, no. 6, 
%   September 2001, pp. 582-589
%
%   melbankm by Mike Brookes 1997
%

%% Assign defaults
if nargin<3 || isempty(hWindow), hWindow = @triang; end

%%
MelFrequencyVector = 2595*log10(1+FrequencyVector/700);   % Convert to mel scale
MaxF = max(MelFrequencyVector);                 % 
MinF = min(MelFrequencyVector);                 %
MelBinWidth = (MaxF-MinF)/(N+1);                %
Filter = zeros([N numel(MelFrequencyVector)]);  % Predefine loop matrix

%% Construct filter bank
for i = 1:N
    iFilter = find(MelFrequencyVector>=((i-1)*MelBinWidth+MinF) & ...
                    MelFrequencyVector<=((i+1)*MelBinWidth+MinF));
    Filter(i,iFilter) = hWindow(numel(iFilter)); % Triangle window
end
Filter = sparse(Filter);    % Reduce memory size

end
